using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace JufGame
{
	[CreateAssetMenu(menuName = ("JufGame/AI/WeightBias"), fileName = ("WeightAndBias_"))]
	public class WeightBiasMemory : ScriptableObject
	{
		[Serializable]
		public struct LayerWeightAndBias
		{
			public int inputCount;
			public int outputCount;
			public float[] weights;
			public float[] bias;
		}
		[Tooltip("各全连层的权重和偏置")]
		public LayerWeightAndBias[] WeiBiasArray;

		[Tooltip("全连接层的compute shader")]
		public ComputeShader affine;

		[Tooltip("激活函数的compute shader")]
		public ComputeShader activateFunc;

		[Tooltip("损失函数的compute shader")]
		public ComputeShader lossFunc;

		[Tooltip("当前损失函数在反向传播时是否要载入上次输出，用于sigmoid等函数")]
		public bool isLoadLastOutput;

		[Header("随机初始化权重")]
		[Tooltip("是否要随机初始化")]
		public bool isRandomWeightAndBias = false;
		
		[Tooltip("当前权重是否是训练成功后的")]
		public bool isFinishedWeightAndBias = false;

		[Tooltip("随机初始化的最大值和最小值")]
		public float minRandValue = -1, maxRandValue = 1;
		
		private void OnValidate()
		{
			if(isRandomWeightAndBias && !isFinishedWeightAndBias)
			{
				RandomWeightAndBias();
				isRandomWeightAndBias = false;
			}
		}

		// 随机初始化权重和偏置
		public void RandomWeightAndBias()
		{
			var rand = new System.Random();
			foreach (var wb in WeiBiasArray)
			{
				float range = maxRandValue - minRandValue;
				// 初始化权重
				for (int i = 0; i < wb.weights.Length; ++i)
				{
					wb.weights[i] = (float)(rand.NextDouble() * range + minRandValue); // 使用指定范围生成随机数
				}
				// 初始化偏置
				for (int i = 0; i < wb.bias.Length; ++i)
				{
					wb.bias[i] = 0;
				}
			}
		}
	}
}
